package com.zhuangjie.rider.vo.PathPlanningVO;

import com.zhuangjie.rider.entity.DeliveryOrder;
import com.zhuangjie.rider.enums.DeliveryOrderState;
import lombok.Getter;

import java.util.*;

public class PathPlanningResultBuilder {
    private Set<ShopForMap> result = new HashSet<>();
    @Getter
    private Map<ShopForMap, List<DinersForMap>> resultOperation = new HashMap<>();

    private Integer nextIndex = 1;


    public Set<ShopForMap> buildResult() {
        return result;
    }

    public PathPlanningResultBuilder(List<DeliveryOrder> deliveryOrderList){
        // shopId 与 对应的ShopForMap（为了快速查找）
        Map<Long, ShopForMap> resultOperationAuxiliary = new HashMap<>();
        deliveryOrderList.forEach(deliveryOrder -> injectToResultOperation(resultOperation,resultOperationAuxiliary, deliveryOrder));

        // 利用Map<ShopForMap, List<DinersForMap>> 构建 Set<ShopForMap>
        for (Map.Entry<ShopForMap, List<DinersForMap>> entry : resultOperation.entrySet()) {
            ShopForMap currentShopForMap = entry.getKey();
            currentShopForMap.setDinersForMaps(new HashSet<>(entry.getValue()));
            result.add(currentShopForMap);
        }

    }

    private void injectToResultOperation(Map<ShopForMap, List<DinersForMap>> resultOperation, Map<Long, ShopForMap> resultOperationAuxiliary, DeliveryOrder deliveryOrder) {
        Long currentShopId = deliveryOrder.getShopId();
        ShopForMap currentShopForMap = resultOperationAuxiliary.get(currentShopId);
        List<DinersForMap> currentDinersForMapsList;
        if (currentShopForMap == null) {
            // 建立初始辅助映射
            currentShopForMap = new ShopForMap(); // key
            currentShopForMap.setId(currentShopId); // 一定要在put到map前，需要先设置shopId，因为map key是否相等是根据ShopForMap的shopId（/id）的
            currentShopForMap.setLongitude(deliveryOrder.getShopLongitude());
            currentShopForMap.setLatitude(deliveryOrder.getShopLatitude());
            currentShopForMap.setShopName(deliveryOrder.getShopName());
            currentShopForMap.setAddressDescribe(deliveryOrder.getShopAddressDescribe());
            currentShopForMap.setIsHasWaitFetchOrder(false);

            currentDinersForMapsList = new ArrayList<>(); // value

            resultOperation.put(currentShopForMap,currentDinersForMapsList);
            resultOperationAuxiliary.put(currentShopId, currentShopForMap);
        }else {
            // 已存在映射，获取currentDinersForMapsList
            currentDinersForMapsList = resultOperation.get(currentShopForMap);
        }
        createDinersForMapAndAddToList(currentShopForMap,currentDinersForMapsList,deliveryOrder);
    }

    /**
     * 为ShopForMap、DinersForMap设置值
     *
     * @param currentShopForMap        当前地图商店
     * @param currentDinersForMapsList 当前地图食客列表
     * @param deliveryOrder            交货订单
     */
    private void createDinersForMapAndAddToList(ShopForMap currentShopForMap, List<DinersForMap> currentDinersForMapsList, DeliveryOrder deliveryOrder) {
        boolean currentOrderIsWaitFetchOrder = deliveryOrder.getDeliveryState() < DeliveryOrderState.RIDER_PICKED_UP.getValue();
        if (currentOrderIsWaitFetchOrder) currentShopForMap.setIsHasWaitFetchOrder(true);
        // 构建当前配送订单的DinersForMap
        DinersForMap currentDinersForMap = new DinersForMap();
        currentDinersForMap.setId(deliveryOrder.getId());
        currentDinersForMap.setLongitude(deliveryOrder.getConsigneeLongitude());
        currentDinersForMap.setLatitude(deliveryOrder.getConsigneeLatitude());
        currentDinersForMap.setConsigneeName(deliveryOrder.getConsigneeFullname());
        currentDinersForMap.setAddressDescribe(deliveryOrder.getConsigneeAddressDescribe());
        currentDinersForMap.setIsWaitFetch(currentOrderIsWaitFetchOrder);
        currentDinersForMap.setCode(deliveryOrder.getCode());
        currentDinersForMap.setShopId(deliveryOrder.getShopId());
        currentDinersForMapsList.add(currentDinersForMap);
    }

    public void putSort(Long shopId) {
        ShopForMap target = findShopForMap(shopId);
        target.setNavigationSort(nextIndex++);
    }

    public void putSort(ShopForMap shopForMap) {
        putSort(shopForMap.getId());
    }

    private ShopForMap findShopForMap(Long shopId) {
        ShopForMap targetShopForMap = null;
        for (ShopForMap shopForMap : result) {
            if (shopForMap.getId().equals(shopId)) targetShopForMap = shopForMap;
        }
        if (targetShopForMap == null) {
            throw new RuntimeException("找不到shopId为"+ shopId);
        }
        return targetShopForMap;
    }


    public void putSort(DinersForMap dinersForMap) {
        ShopForMap shopForMap = findShopForMap(dinersForMap.getShopId());
        dinersForMap = findDinersForMap(shopForMap.getDinersForMaps(),dinersForMap.getId());
        dinersForMap.setNavigationSort(nextIndex++);
    }

    private DinersForMap findDinersForMap(Collection<DinersForMap> dinersForMaps, Long dinersId) {
        DinersForMap targetDinersForMap = null;
        for (DinersForMap dinersForMap : dinersForMaps) {
            if (dinersForMap.getId().equals(dinersId)) targetDinersForMap = dinersForMap;
        }
        if (targetDinersForMap == null) {
            throw new RuntimeException("找不到dinersId为"+ dinersId);
        }
        return targetDinersForMap;

    }


}
